using System;
using System.Text;
using System.Diagnostics;
using System.Collections.Generic;
using System.Collections.Specialized;

namespace My.IdlConverter.Core
{
    using Filters;

    public class Class : Interface
    {
        private IList<Interface> _baseInterfaces = new List<Interface>();

        public Class(string name)
            :base(name)
        {
            Abstract = false;
        }

        public override Method this[int index]
        {
            get
            {
                return Methods[index];
            }
        }

        public override Method this[string name]
        {
            get
            {
                foreach (Method nextMethod in Methods)
                {
                    if (nextMethod.Name.Equals(name))
                        return nextMethod;
                }
                return null;
            }
        }

        public IList<Interface> BaseInterfaces
        {
            get
            {
                return _baseInterfaces;
            }
        }

        public void GetBaseClasses(ref IList<Class> baseClasses)
        {
            foreach (Interface nextInterface in BaseInterfaces)
            {
                if (nextInterface == null)
                    continue;

                if (nextInterface.IsClass())
                {
                    Class classObj = nextInterface as Class;
                    Debug.Assert(classObj != null);
                    baseClasses.Add(classObj);
                    classObj.GetBaseClasses(ref baseClasses);
                }
            }
        }

        public void GetPureBaseInterfaces(ref IList<Interface> pureBaseInterfaces)
        {
            foreach (Interface nextInterface in BaseInterfaces)
            {
                if (nextInterface == null)
                    continue;
                if (nextInterface.IsClass())
                {
                    Class classObj = nextInterface as Class;
                    Debug.Assert(classObj != null);
                    classObj.GetPureBaseInterfaces(ref pureBaseInterfaces);
                }
                else
                {
                    pureBaseInterfaces.Add(nextInterface);
                }
            }
        }

        public override bool IsClass()
        {
            return true;
        }

        public virtual bool HasBaseClass
        {
            get
            {
                if (_baseInterfaces == null) 
                    return false;
                if (_baseInterfaces.Count > 0)
                {
                    foreach (Interface nextInterface in _baseInterfaces)
                    {
                        if (nextInterface == null)
                            continue;
                        if (nextInterface.IsClass())
                            return true;
                    }
                }
                return false;
            }
        }

        public override int Depth
        {
            get
            {
                if (!HasBaseClass)
                    return 1;
                int depth = 1;
                foreach (Interface nextInterface in _baseInterfaces)
                {
                    if (nextInterface.IsClass())
                    {
                        int subDepth = nextInterface.Depth;
                        if (subDepth > depth)
                            depth = subDepth;
                    }
                }

                return depth;
            }
        }

        public Interface DefaultBaseInterface
        {
            get
            {
                IList<Interface> pureBaseInterfaces = new List<Interface>();
                GetPureBaseInterfaces(ref pureBaseInterfaces);
                foreach (Interface nextInterface in pureBaseInterfaces)
                {
                    if (ClueWord.Equals(nextInterface.ClueWord))
                    {
                        return nextInterface;
                    }
                }
                return null;
            }
        }

        public override string ClueWord
        {
            get
            {
                return ClassModifier.GetTitle(Name);
            }
        }

        public bool IsLone()
        {
            return (_baseInterfaces.Count == 1);
        }
    }

}
